package com.movecar.utils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.util.Log;
import android.util.TypedValue;

/**
 * @class：BitMapUtil.java
 * @description: bitmap处理工具类
 * @author Zhao.JQ
 * @history:
 * 
 * 
 */
public class BitMapUtil {
	static int textSize = 12;
	static Bitmap mergeBitmapBack = null;
	static Bitmap balloonBundle = null;
	public static final String Angle_TMP_FILE_DIR_NAME = "temp_change_angle_img";

	private static final int MAX_BITMAP_WIDTH = 1024;
	private static final int MAX_BITMAP_HEIGHT = 2048;

	/**
	 * @description 获得圆形图片
	 * @param bitmap
	 * @return
	 */
	public static Bitmap getRoundedCornerBitmap(final Bitmap bitmap) {
		final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		final Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawOval(rectF, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	/**
	 * 获得圆角图片
	 * 
	 * @param bitmap
	 * @param roundPx
	 *            5 10
	 * @return
	 */
	public static Bitmap getRoundedCornerBitmap(final Bitmap bitmap, final float roundPx) {
		final int w = bitmap.getWidth();
		final int h = bitmap.getHeight();
		final Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
		final Canvas canvas = new Canvas(output);
		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, w, h);
		final RectF rectF = new RectF(rect);
		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	public static Bitmap returnBitMap(String url) {
		Log.i("returnBitMap", "url=" + url);
		URL myFileUrl = null;
		Bitmap bitmap = null;
		try {
			myFileUrl = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bitmap;
	}

	public static Bitmap drawableToBitmap(final Drawable drawable) {
		// 取 drawable 的长宽
		final int w = drawable.getIntrinsicWidth();
		final int h = drawable.getIntrinsicHeight();

		// 取 drawable 的颜色格式
		final Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
				: Bitmap.Config.RGB_565;
		// 建立对应 bitmap
		final Bitmap bitmap = Bitmap.createBitmap(w, h, config);
		// 建立对应 bitmap 的画布
		final Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, w, h);
		// 把 drawable 内容画到画布中
		drawable.draw(canvas);
		return bitmap;
	}

	/**
	 * @description 组合图片
	 * @param 上层图
	 *            （显示圆形图片）
	 * @return
	 */
	public static Bitmap mergeBitmap(final Bitmap fore) {

		if (BitMapUtil.mergeBitmapBack == null) {
			// BitMapUtil.mergeBitmapBack =
			// BitMapUtil.decodeResource(QQMaoApplication.QQMaoApp.getResources(),
			// R.drawable.map_user);
		}

		final Bitmap targetBitmap = Bitmap.createBitmap(BitMapUtil.mergeBitmapBack.getWidth(),
				BitMapUtil.mergeBitmapBack.getHeight(), Config.ARGB_8888);

		final float widthf = fore.getWidth();
		final float heightf = fore.getHeight();
		final Matrix matrixf = new Matrix();
		final float scaleWidhtf = (BitMapUtil.mergeBitmapBack.getWidth() - 8) / widthf;
		final float scaleHeightf = (BitMapUtil.mergeBitmapBack.getWidth() - 8) / heightf;
		matrixf.postScale(scaleWidhtf, scaleHeightf);
		final Bitmap newfore = Bitmap.createBitmap(fore, 0, 0, fore.getWidth(), fore.getHeight(), matrixf, true);

		final Canvas cv = new Canvas(targetBitmap);
		cv.drawBitmap(BitMapUtil.mergeBitmapBack, 0, 0, null);// 在 0，0坐标开始画入bg
		cv.drawBitmap(BitMapUtil.getRoundedCornerBitmap(newfore), 4, 4, null);
		cv.save(Canvas.ALL_SAVE_FLAG);// 保存

		return targetBitmap;

	}

	public static Bitmap usersBitmap(final Bitmap fore, final int userCount) {
		if (BitMapUtil.mergeBitmapBack == null) {
			// BitMapUtil.mergeBitmapBack =
			// BitMapUtil.decodeResource(QQMaoApplication.QQMaoApp.getResources(),
			// R.drawable.map_user);
		}

		final Bitmap targetBitmap = Bitmap.createBitmap(BitMapUtil.mergeBitmapBack.getWidth(),
				(int) (BitMapUtil.mergeBitmapBack.getHeight() * 1.2), Config.ARGB_8888);

		final Canvas cv = new Canvas(targetBitmap);
		cv.drawBitmap(BitMapUtil.mergeBitmapBack, 0, (int) (BitMapUtil.mergeBitmapBack.getHeight() * 0.2), null);
		if (fore != null) {

			final float widthf = fore.getWidth();
			final float heightf = fore.getHeight();
			final Matrix matrixf = new Matrix();
			final float scaleWidhtf = (BitMapUtil.mergeBitmapBack.getWidth() - 8) / widthf;
			final float scaleHeightf = (BitMapUtil.mergeBitmapBack.getWidth() - 8) / heightf;
			matrixf.postScale(scaleWidhtf, scaleHeightf);
			final Bitmap newfore = Bitmap.createBitmap(fore, 0, 0, fore.getWidth(), fore.getHeight(), matrixf, true);

			cv.drawBitmap(BitMapUtil.getRoundedCornerBitmap(newfore), 4,
					(int) (BitMapUtil.mergeBitmapBack.getHeight() * 0.2) + 4, null);
		}

		final Paint paintNum = new Paint();
		paintNum.setColor(Color.WHITE);
		paintNum.setAntiAlias(true);
		paintNum.setTextSize(BitMapUtil.textSize * 1);
		final Paint pRect = new Paint();
		pRect.setColor(Color.RED);
		pRect.setAntiAlias(true);
		pRect.setAlpha(150);
		cv.drawRoundRect(
				new RectF(2 * 1 + BitMapUtil.mergeBitmapBack.getWidth() / 4, 0, BitMapUtil.mergeBitmapBack.getWidth()
						- (2 * 1 + BitMapUtil.mergeBitmapBack.getWidth() / 4),
						BitMapUtil.mergeBitmapBack.getHeight() / 6 + 2), 2 * 1, 2 * 1, pRect);
		if (userCount < 10) {
			cv.drawText(String.valueOf(userCount), BitMapUtil.textSize * 1 + BitMapUtil.mergeBitmapBack.getWidth() / 4,
					BitMapUtil.textSize * 1, paintNum);
		} else {
			cv.drawText(String.valueOf(userCount),
					(int) (BitMapUtil.textSize * 1.5 + BitMapUtil.mergeBitmapBack.getWidth() / 4),
					BitMapUtil.textSize * 1, paintNum);
		}
		cv.save(Canvas.ALL_SAVE_FLAG);

		return targetBitmap;

	}

	public static Bitmap balloonsBitmap(final int balloonCount) {
		if (BitMapUtil.balloonBundle == null) {
			// BitMapUtil.balloonBundle =
			// BitMapUtil.decodeResource(QQMaoApplication.QQMaoApp.getResources(),
			// R.drawable.balloon_bundle);
		}
		final Bitmap newbmp = Bitmap.createBitmap(BitMapUtil.balloonBundle.getWidth(),
				(int) (BitMapUtil.balloonBundle.getHeight() * 1.4), Config.ARGB_8888);
		final Canvas cv = new Canvas(newbmp);
		cv.drawBitmap(BitMapUtil.balloonBundle, 0, BitMapUtil.balloonBundle.getHeight() * 0.4f, null);
		final Paint paintNum = new Paint();
		paintNum.setColor(Color.WHITE);
		paintNum.setAntiAlias(true);
		paintNum.setTextSize(BitMapUtil.textSize * 1);
		final Paint pRect = new Paint();
		pRect.setColor(Color.RED);
		pRect.setAntiAlias(true);
		pRect.setAlpha(150);
		cv.drawRoundRect(
				new RectF(2 * 1, 0, BitMapUtil.balloonBundle.getWidth() - 2 * 1,
						BitMapUtil.balloonBundle.getHeight() / 3), 2 * 1, 2 * 1, pRect);
		if (balloonCount < 10) {
			cv.drawText(String.valueOf(balloonCount), BitMapUtil.textSize * 1, BitMapUtil.textSize * 1, paintNum);
		} else {
			cv.drawText(String.valueOf(balloonCount), (int) (BitMapUtil.textSize * 1.5), BitMapUtil.textSize * 1,
					paintNum);
		}

		cv.save(Canvas.ALL_SAVE_FLAG);

		return newbmp;

	}

	private static Bitmap decodeResource(final Resources resources, final int id) {
		final TypedValue value = new TypedValue();
		resources.openRawResource(id, value);
		final BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inTargetDensity = value.density;
		return BitmapFactory.decodeResource(resources, id, opts);
	}

	/**
	 * Bitmap to drawable
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Drawable bitmapToDrawable(final Bitmap bitmap) {
		return new BitmapDrawable(bitmap);
	}

	/**
	 * Input stream to bitmap
	 * 
	 * @param inputStream
	 * @return
	 * @throws Exception
	 */
	public static Bitmap inputStreamToBitmap(final InputStream inputStream) throws Exception {
		return BitmapFactory.decodeStream(inputStream);
	}

	/**
	 * Byte transfer to bitmap
	 * 
	 * @param byteArray
	 * @return
	 */
	public static Bitmap byteToBitmap(final byte[] byteArray) {
		if (byteArray.length != 0)
			return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
		else
			return null;
	}

	/**
	 * Byte transfer to drawable
	 * 
	 * @param byteArray
	 * @return
	 */
	public static Drawable byteToDrawable(final byte[] byteArray) {
		ByteArrayInputStream ins = null;
		if (byteArray != null) {
			ins = new ByteArrayInputStream(byteArray);
		}
		return Drawable.createFromStream(ins, null);
	}

	/**
	 * Bitmap transfer to bytes
	 * 
	 * @param byteArray
	 * @return
	 */
	public static byte[] bitmapToBytes(final Bitmap bm) {
		byte[] bytes = null;
		if (bm != null) {
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
			bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
			bytes = baos.toByteArray();
		}
		return bytes;
	}

	/**
	 * Drawable transfer to bytes
	 * 
	 * @param drawable
	 * @return
	 */
	public static byte[] drawableToBytes(final Drawable drawable) {
		final BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
		final Bitmap bitmap = bitmapDrawable.getBitmap();
		final byte[] bytes = BitMapUtil.bitmapToBytes(bitmap);
		;
		return bytes;
	}

	/**
	 * Base64 to byte[] //
	 */
	// public static byte[] base64ToBytes(String base64) throws IOException {
	// byte[] bytes = Base64.decode(base64);
	// return bytes;
	// }
	//
	// /**
	// * Byte[] to base64
	// */
	// public static String bytesTobase64(byte[] bytes) {
	// String base64 = Base64.encode(bytes);
	// return base64;
	// }

	/**
	 * 获得带倒影的图片
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap createReflectionImageWithOrigin(final Bitmap bitmap) {
		final int reflectionGap = 4;
		final int w = bitmap.getWidth();
		final int h = bitmap.getHeight();

		final Matrix matrix = new Matrix();
		matrix.preScale(1, -1);

		final Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w, h / 2, matrix, false);

		final Bitmap bitmapWithReflection = Bitmap.createBitmap(w, h + h / 2, Config.ARGB_8888);

		final Canvas canvas = new Canvas(bitmapWithReflection);
		canvas.drawBitmap(bitmap, 0, 0, null);
		final Paint deafalutPaint = new Paint();
		canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint);

		canvas.drawBitmap(reflectionImage, 0, h + reflectionGap, null);

		final Paint paint = new Paint();
		final LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight()
				+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
		paint.setShader(shader);
		// Set the Transfer mode to be porter duff and destination in
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		// Draw a rectangle using the paint with our linear gradient
		canvas.drawRect(0, h, w, bitmapWithReflection.getHeight() + reflectionGap, paint);

		return bitmapWithReflection;
	}

	/**
	 * 放大缩小图片
	 * 
	 * @param bitmap
	 * @param width
	 * @param height
	 * @return
	 */
	public static Bitmap zoomBitmap(final Bitmap bitmap, final int width, final int height) {
		final int w = bitmap.getWidth();
		final int h = bitmap.getHeight();
		final Matrix matrix = new Matrix();
		final float scaleWidth = (float) width / w;
		final float scaleHeight = (float) height / h;
		matrix.postScale(scaleWidth, scaleHeight);
		final Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
		return newbmp;
	}

	/**
	 * 放大缩小drawable
	 * 
	 * @param drawable
	 * @param w
	 * @param h
	 * @return
	 */
	public static Drawable zoomDrawable(final Drawable drawable, final int w, final int h) {
		final int width = drawable.getIntrinsicWidth();
		final int height = drawable.getIntrinsicHeight();
		final Bitmap oldbmp = BitMapUtil.drawableToBitmap(drawable);
		final Matrix matrix = new Matrix();
		final float sx = (float) w / width;
		final float sy = (float) h / height;
		matrix.postScale(sx, sy);
		final Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
		return new BitmapDrawable(newbmp);
	}

	/**
	 * Get images from SD card by path and the name of image
	 * 
	 * @param photoName
	 * @return
	 */
	public static Bitmap getPhotoFromSDCard(final String path, final String photoName) {
		final Bitmap photoBitmap = BitmapFactory.decodeFile(path + "/" + photoName + ".png");
		if (photoBitmap == null)
			return null;
		else
			return photoBitmap;
	}

	/**
	 * 获取合适的bitmap，避免发生OOM
	 * 
	 * @param file
	 * @return
	 */
	public static Bitmap getSuitableBitmap(File file) {
		Bitmap bitmap = null;
		try {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;
			FileInputStream fis = new FileInputStream(file);
			bitmap = BitmapFactory.decodeStream(fis, null, options);

			int sum = options.outWidth * options.outHeight;

			if (sum > 640000 || options.outWidth > MAX_BITMAP_WIDTH || options.outHeight > MAX_BITMAP_HEIGHT) { // 图片太大
				float scale = (float) Math.sqrt(sum / 500000.0f);
				float extScale = 0.0f;
				if (options.outWidth > MAX_BITMAP_WIDTH) {
					extScale = (float) ((float) (options.outWidth) / (float) (MAX_BITMAP_WIDTH / 2 + 256));
				}
				if (options.outHeight > MAX_BITMAP_HEIGHT) {
					float tmpScale = (float) ((float) (options.outHeight) / (float) (MAX_BITMAP_HEIGHT / 2 + 256));
					if (tmpScale > extScale) {
						extScale = tmpScale;
					}
				}
				float totalScale = scale + extScale;
				options.outWidth /= totalScale;
				options.outHeight /= totalScale;
				options.inSampleSize = (int) (Math.ceil(totalScale));
				// options.inPreferredConfig = Bitmap.Config.ARGB_4444;
				options.inPreferredConfig = Bitmap.Config.RGB_565;
				options.inDither = false; // Disable Dithering mode
				options.inPurgeable = true; // Tell to gc that whether it needs
											// free memory, the Bitmap can be
											// cleared
				options.inInputShareable = true; // Which kind of reference will
													// be used to recover the
													// Bitmap data after being
													// clear, when it will be
													// used in the future

			}
			options.inJustDecodeBounds = false;

			fis = new FileInputStream(file);
			bitmap = BitmapFactory.decodeStream(fis, null, options);
		} catch (Exception e) {
			return null;
		}
		return bitmap;
	}

	/*
	 * 依角度转换图片并保存
	 */
	public static String getNormalPic(Context context, int angle, String path) {
		String filePath = path;
		if (angle > 0) {

			Bitmap bitmap = getSuitableBitmap(new File(filePath));
			bitmap = rotaingImageView(angle, bitmap);
			if (null == bitmap) {
				return null;
			}
		}
		return filePath;
	}

	/**
	 * 读取图片属性：旋转的角度
	 * 
	 * @param path
	 *            图片绝对路径
	 * @return degree旋转的角度
	 */
	public static int readPictureDegree(String path) {
		int degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				degree = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				degree = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				degree = 270;
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return degree;
	}

	/*
	 * 旋转图片
	 * 
	 * @param angle
	 * 
	 * @param bitmap
	 * 
	 * @return Bitmap
	 */
	public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
		// 旋转图片 动作
		Matrix matrix = new Matrix();

		matrix.postRotate(angle);
		System.out.println("angle2=" + angle);
		// 创建新的图片

		Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

		return resizedBitmap;

	}

	public static byte[] getByteBufferByBitmap(Bitmap bm) {
		byte[] buffer = null;
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.JPEG, 90, stream);
		buffer = stream.toByteArray();
		return buffer;
	}

	public static Bitmap getBitmapByByte(byte[] picBuffer) {

		if (picBuffer.length != 0) {
			return getBitmapFromFile(picBuffer, 1280, 1280);
		}
		return null;
	}

	public static Bitmap getSmallBitmap(String filePath) {

		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filePath, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, 1280, 1280);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;

		Bitmap bm = BitmapFactory.decodeFile(filePath, options);
		if (bm == null) {
			return null;
		}

		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);

		} finally {
			try {
				if (baos != null)
					baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return bm;

	}

	private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			// Calculate ratios of height and width to requested height and
			// width
			final int heightRatio = Math.round((float) height / (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);

			// Choose the smallest ratio as inSampleSize value, this will
			// guarantee
			// a final image with both dimensions larger than or equal to the
			// requested height and width.
			inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
		}

		return inSampleSize;
	}

	public static Bitmap getBitmapFromFile(byte[] picBuffer, int width, int height) {
		BitmapFactory.Options opts = null;
		if (width > 0 && height > 0) {
			opts = new BitmapFactory.Options();
			opts.inJustDecodeBounds = true;
			BitmapFactory.decodeByteArray(picBuffer, 0, picBuffer.length, opts);
			// 计算图片缩放比例
			final int minSideLength = Math.min(width, height);
			opts.inSampleSize = computeSampleSize(opts, minSideLength, width * height);
			opts.inJustDecodeBounds = false;
			opts.inInputShareable = true;
			opts.inPurgeable = true;
		}
		try {
			return resetRotate(BitmapFactory.decodeByteArray(picBuffer, 0, picBuffer.length, opts), 0, null);
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
		}
		return null;
	}

	public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	private static Bitmap resetRotate(Bitmap bitmap, int rotate, String path) {
		// bitmap = resizeBitmap(bitmap, 600, 600);
		Matrix m = new Matrix();
		m.setRotate(rotate, (float) bitmap.getWidth(), (float) bitmap.getHeight());
		Bitmap b2 = null;
		try {
			b2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
		} catch (OutOfMemoryError e) {
			b2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2, m, true);
		}

		if (bitmap != b2) {
			bitmap.recycle(); // Android开发网再次提示Bitmap操作完应该显示的释放
			bitmap = null;
			bitmap = b2;

		}
		if (path != null) {
			try {
				FileOutputStream b = new FileOutputStream(path);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
				// b2.recycle();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
		// Bitmap cameraBitmap = BitmapFactory.decodeFile(path, bitmapOptions);
		return bitmap;

	}

	private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength),
				Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}

	public static Bitmap getBitmapFromFile(File dst, int width, int height) {
		if (null != dst && dst.exists()) {
			BitmapFactory.Options opts = null;
			if (width > 0 && height > 0) {
				opts = new BitmapFactory.Options();
				opts.inJustDecodeBounds = true;
				BitmapFactory.decodeFile(dst.getPath(), opts);
				// 计算图片缩放比例
				final int minSideLength = Math.min(width, height);
				opts.inSampleSize = computeSampleSize(opts, minSideLength, width * height);
				opts.inJustDecodeBounds = false;
				opts.inInputShareable = true;
				opts.inPurgeable = true;
			}
			try {
				return BitmapFactory.decodeFile(dst.getPath(), opts);
			} catch (OutOfMemoryError e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/** */
	/**
	 * 把字节数组保存为一个文件
	 */
	public static File getFileFromBytes(byte[] b, File outputFile) {
		BufferedOutputStream stream = null;
		File file = null;
		try {
			file = outputFile;
			FileOutputStream fstream = new FileOutputStream(file);
			stream = new BufferedOutputStream(fstream);
			stream.write(b);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return file;
	}

	public static Bitmap comp(Bitmap image) {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 60, baos);
		if (baos.toByteArray().length / 1024 > 1024) {// 判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 这里压缩50%，把压缩后的数据存放到baos中
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		// 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
		float hh = 800f;// 这里设置高度为800f
		float ww = 480f;// 这里设置宽度为480f
		// 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
		int be = 1;// be=1表示不缩放
		if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;// 设置缩放比例
		// 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		isBm = new ByteArrayInputStream(baos.toByteArray());
		bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
	}

	public static Bitmap compressImage(Bitmap image) {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 60, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
		int options = 100;
		while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
			options -= 10;// 每次都减少10
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
		return bitmap;
	}

}
